import { useState, useEffect, useRef, useCallback } from 'react'
import { Button } from '@/components/ui/button'
import { AlertCircle, Play, Pause, X, Grip, Crop, Camera, ZoomIn, ZoomOut, RotateCcw, Volume2, Minimize2, Maximize2 } from 'lucide-react'
import { createWorker, PSM } from 'tesseract.js'

export default function LiveWakeupFloating() {
  // 检查 IPC 是否可用
  const [ipcAvailable] = useState(() => {
    // console.log('[悬浮窗] 初始化 - 检查环境...')
    // console.log('[悬浮窗] window 对象存在:', !!window)
    // console.log('[悬浮窗] window.ipcRenderer 存在:', !!window.ipcRenderer)
    // console.log('[悬浮窗] window 的所有属性:', Object.keys(window).filter(k => k.includes('ipc') || k.includes('electron')))
    
    const available = !!window.ipcRenderer
    if (!available) {
      console.error('[悬浮窗] ❌ IPC 通信不可用，请检查 preload 脚本')
      console.error('[悬浮窗] 当前 URL:', window.location.href)
    } else {
      console.log('[悬浮窗] ✅ IPC 通信可用')
    }
    return available
  })

  // 监控状态
  const [isMonitoring, setIsMonitoring] = useState(false)
  const [ocrReady, setOcrReady] = useState(false)
  const [checkInterval, setCheckInterval] = useState(() => {
    const saved = localStorage.getItem('liveWakeup:checkInterval')
    return saved ? parseInt(saved) : 3
  })
  const [countdown, setCountdown] = useState(0) // 倒计时状态
  
  // OCR引擎配置（从localStorage读取）
  const [ocrEngine] = useState<'tesseract' | 'umi-ocr'>(() => {
    const saved = localStorage.getItem('liveWakeup:ocrEngine')
    const engine = (saved as 'tesseract' | 'umi-ocr') || 'tesseract'
    console.log('[悬浮窗-配置] OCR引擎:', engine)
    return engine
  })
  const [umiOcrApiUrl] = useState(() => {
    const saved = localStorage.getItem('liveWakeup:umiOcrApiUrl')
    const url = saved || 'http://localhost:1224'
    console.log('[悬浮窗-配置] Umi-OCR API:', url)
    return url
  })
  const [umiOcrLanguage] = useState(() => {
    const saved = localStorage.getItem('liveWakeup:umiOcrLanguage')
    const lang = saved || 'chi_sim'
    console.log('[悬浮窗-配置] Umi-OCR 语言:', lang)
    return lang
  })
  
  // 叫醒模式配置（从localStorage读取）
  const [wakeupMode] = useState<'audio' | 'phone'>(() => {
    const saved = localStorage.getItem('liveWakeup:wakeupMode')
    const mode = (saved as 'audio' | 'phone') || 'audio'
    console.log('[悬浮窗-配置] 叫醒模式:', mode, '(localStorage值:', saved, ')')
    return mode
  })
  const [phoneNumber] = useState(() => {
    const saved = localStorage.getItem('liveWakeup:phoneNumber')
    const phone = saved || ''
    console.log('[悬浮窗-配置] 电话号码:', phone ? '已设置' : '未设置')
    return phone
  })
  const [audioFilePath, setAudioFilePath] = useState(() => {
    const saved = localStorage.getItem('liveWakeup:audioFilePath')
    const path = saved || ''
    console.log('[悬浮窗-配置] 音频文件路径:', path || '未设置（将使用默认音）')
    return path
  })
  const [alertVolume, setAlertVolume] = useState(() => {
    // 主窗口保存的是字符串数字，不是数组
    const saved = localStorage.getItem('liveWakeup:alertVolume')
    const volume = saved ? parseInt(saved) : 80
    console.log('[悬浮窗-配置] 音量:', volume)
    return volume
  })
  const [alertRepeat, setAlertRepeat] = useState(() => {
    // 主窗口保存的是字符串数字，不是数组
    const saved = localStorage.getItem('liveWakeup:alertRepeat')
    const repeat = saved ? parseInt(saved) : 0
    console.log('[悬浮窗-配置] 循环次数:', repeat === 0 ? '无限循环' : repeat + '次')
    return repeat
  })
  
  // 🔄 监听 localStorage 变化，实时更新配置
  useEffect(() => {
    const handleStorageChange = (e: StorageEvent) => {
      if (e.key === 'liveWakeup:audioFilePath' && e.newValue !== null) {
        console.log('[悬浮窗-配置] 音频文件路径已更新:', e.newValue)
        setAudioFilePath(e.newValue)
      } else if (e.key === 'liveWakeup:alertVolume' && e.newValue !== null) {
        const volume = parseInt(e.newValue)
        console.log('[悬浮窗-配置] 音量已更新:', volume)
        setAlertVolume(volume)
      } else if (e.key === 'liveWakeup:alertRepeat' && e.newValue !== null) {
        const repeat = parseInt(e.newValue)
        console.log('[悬浮窗-配置] 循环次数已更新:', repeat === 0 ? '无限循环' : repeat + '次')
        setAlertRepeat(repeat)
      } else if (e.key === 'liveWakeup:checkInterval' && e.newValue !== null) {
        const interval = parseInt(e.newValue)
        console.log('[悬浮窗-配置] 检测间隔已更新:', interval, '秒')
        setCheckInterval(interval)
      }
    }
    
    window.addEventListener('storage', handleStorageChange)
    
    return () => {
      window.removeEventListener('storage', handleStorageChange)
    }
  }, [])

  // ⏱️ 倒计时定时器
  useEffect(() => {
    if (!isMonitoring) {
      setCountdown(0)
      return
    }

    // 监控启动时初始化倒计时
    setCountdown(checkInterval)

    const timer = setInterval(() => {
      setCountdown(prev => {
        if (prev <= 1) {
          // 倒计时结束，重新开始
          return checkInterval
        }
        return prev - 1
      })
    }, 1000)

    return () => {
      clearInterval(timer)
    }
  }, [isMonitoring, checkInterval])
  const [aliCloudInitialized, setAliCloudInitialized] = useState(false)
  
  // 警报状态
  const [alertActive, setAlertActive] = useState(false)
  const [lastKeyword, setLastKeyword] = useState<string>('')
  
  // 区域选择状态 - 每次启动都要重新选择，不使用 localStorage
  const [captureRegion, setCaptureRegion] = useState<{
    x: number
    y: number
    width: number
    height: number
  } | null>(null)
  const [isSelectingRegion, setIsSelectingRegion] = useState(false)
  
  // 测试截图状态
  const [testScreenshot, setTestScreenshot] = useState<string | null>(null)
  const [isTestingScreenshot, setIsTestingScreenshot] = useState(false)
  const [showScreenshotPreview, setShowScreenshotPreview] = useState(false)
  const [showEnlargedPreview, setShowEnlargedPreview] = useState(false)
  
  // 测试音频播放状态
  const [isTestingAudio, setIsTestingAudio] = useState(false)
  const isTestingAudioRef = useRef(false)
  
  // 图片缩放和拖拽状态
  const [imageScale, setImageScale] = useState(1)
  const [imagePosition, setImagePosition] = useState({ x: 0, y: 0 })
  const [isImageDragging, setIsImageDragging] = useState(false)
  const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 })
  
  // 窗口拖动状态（原有的）
  const [isWindowDragging, setIsWindowDragging] = useState(false)
  
  // OCR Worker 引用
  const ocrWorkerRef = useRef<Awaited<ReturnType<typeof createWorker>> | null>(null)
  
  // 使用 ref 立即追踪监控状态
  const isMonitoringRef = useRef(false)
  
  // 音频引用
  const alertIntervalRef = useRef<NodeJS.Timeout | null>(null)
  const audioContextRef = useRef<AudioContext | null>(null)
  const currentAlertActive = useRef(false)
  const audioContextInitialized = useRef(false)
  const customAudioRef = useRef<HTMLAudioElement | null>(null)
  
  // 拖动相关
  const [isDragging, setIsDragging] = useState(false)
  
  // 简洁模式状态
  const [compactMode, setCompactMode] = useState(() => {
    const saved = localStorage.getItem('liveWakeup:compactMode')
    return saved === 'true'
  })

  // 检查阿里云配置状态
  useEffect(() => {
    async function checkAliCloudConfig() {
      if (wakeupMode === 'phone' && window.ipcRenderer) {
        try {
          const result = await window.ipcRenderer.invoke('liveWakeup:getConfigStatus' as any)
          if (result.success && result.status.isConfigured) {
            setAliCloudInitialized(true)
            console.log('[悬浮窗] 阿里云语音服务配置已就绪')
          } else {
            setAliCloudInitialized(false)
            console.log('[悬浮窗] 阿里云语音服务未配置')
          }
        } catch (error) {
          console.error('[悬浮窗] 检查阿里云配置状态失败:', error)
          setAliCloudInitialized(false)
        }
      }
    }

    checkAliCloudConfig()
  }, [wakeupMode])

  // 监听主进程发送的音频播放请求（用于播放自定义音频文件）
  useEffect(() => {
    if (!window.ipcRenderer) {
      return
    }

    const handlePlayAudio = (base64Audio: string, volume: number = 100) => {
      console.log('[悬浮窗-自定义音频] 收到播放音频请求，音量:', volume)
      
      // 检查是否应该停止（用户手动停止了）
      if (!currentAlertActive.current && !isTestingAudioRef.current) {
        console.log('[悬浮窗-自定义音频] 用户已停止播放，忽略此请求')
        return
      }
      
      try {
        // 停止并清理之前的音频
        if (customAudioRef.current) {
          const oldAudio = customAudioRef.current
          oldAudio.pause()
          oldAudio.src = '' // 清空 src
          oldAudio.onended = null
          oldAudio.onerror = null
          customAudioRef.current = null
        }

        // 等待一小段时间，确保之前的音频完全释放
        setTimeout(() => {
          try {
            // 创建新的 Audio 元素
            const audio = new Audio()
            customAudioRef.current = audio
            
            // 设置音量
            audio.volume = volume / 100
          
            // 将 base64 转换为 blob URL
            const binaryString = atob(base64Audio)
            const bytes = new Uint8Array(binaryString.length)
            for (let i = 0; i < binaryString.length; i++) {
              bytes[i] = binaryString.charCodeAt(i)
            }
            const blob = new Blob([bytes], { type: 'audio/mpeg' })
            const url = URL.createObjectURL(blob)
            
            audio.src = url
            
            // 监听播放完成
            audio.onended = () => {
              console.log('[悬浮窗-自定义音频] 播放完成')
              URL.revokeObjectURL(url)
              // 如果是测试音频，重置状态
              setIsTestingAudio(false)
              isTestingAudioRef.current = false
              if (window.ipcRenderer) {
                window.ipcRenderer.send('tts:play-complete')
              }
            }
            
            // 监听播放错误
            audio.onerror = (error) => {
              console.error('[悬浮窗-自定义音频] 播放失败:', error)
              URL.revokeObjectURL(url)
              // 只有在非用户主动停止的情况下才报错
              if (currentAlertActive.current || isTestingAudioRef.current) {
                setIsTestingAudio(false)
                isTestingAudioRef.current = false
                if (window.ipcRenderer) {
                  window.ipcRenderer.send('tts:play-error', '播放失败')
                }
              }
            }
            
            // 开始播放
            audio.play().then(() => {
              console.log('[悬浮窗-自定义音频] 开始播放')
            }).catch((error) => {
              console.error('[悬浮窗-自定义音频] 播放失败:', error)
              setIsTestingAudio(false)
              isTestingAudioRef.current = false
              if (window.ipcRenderer) {
                window.ipcRenderer.send('tts:play-error', error.message)
              }
            })
          } catch (innerError) {
            console.error('[悬浮窗-自定义音频] setTimeout 内部错误:', innerError)
            setIsTestingAudio(false)
            isTestingAudioRef.current = false
            if (window.ipcRenderer) {
              window.ipcRenderer.send('tts:play-error', innerError instanceof Error ? innerError.message : '未知错误')
            }
          }
        }, 50) // 50ms 延迟，确保前一个音频完全释放
      } catch (error) {
        console.error('[悬浮窗-自定义音频] 处理音频数据失败:', error)
        setIsTestingAudio(false)
        isTestingAudioRef.current = false
        if (window.ipcRenderer) {
          window.ipcRenderer.send('tts:play-error', error instanceof Error ? error.message : '未知错误')
        }
      }
    }

    const unsubscribe = window.ipcRenderer.on('tts:play-audio', handlePlayAudio)

    // 监听停止音频请求
    const handleStopAudio = () => {
      console.log('[悬浮窗-自定义音频] 收到停止音频请求')
      if (customAudioRef.current) {
        customAudioRef.current.pause()
        customAudioRef.current = null
      }
    }

    const unsubscribeStop = window.ipcRenderer.on('tts:stop-audio', handleStopAudio)

    return () => {
      unsubscribe()
      unsubscribeStop()
      if (customAudioRef.current) {
        customAudioRef.current.pause()
        customAudioRef.current = null
      }
    }
  }, [])

  // 初始化 OCR Worker（仅在使用 Tesseract 引擎时）
  useEffect(() => {
    async function initOCR() {
      // 如果使用 Umi-OCR，跳过 Tesseract 初始化
      if (ocrEngine === 'umi-ocr') {
        console.log('[悬浮窗] 使用 Umi-OCR 引擎，跳过 Tesseract 初始化')
        setOcrReady(true)
        return
      }

      try {
        console.log('[悬浮窗] Tesseract 引擎开始初始化（优化配置）...')
        const worker = await createWorker('chi_sim', 1, {
          logger: (m) => {
            if (m.status === 'initializing language' || m.status === 'initialized api') {
              console.log('[悬浮窗-OCR]', m.status)
            }
          },
          workerPath: '/tesseract/worker.min.js',
          langPath: 'https://tessdata.projectnaptha.com/4.0.0',
        })
        
        // ⚡ 优化配置：提升识别速度和准确率
        await worker.setParameters({
          tessedit_pageseg_mode: PSM.SINGLE_BLOCK,  // 假设文本块统一（适合直播场景）
          tessedit_char_whitelist: '',               // 不限制字符（识别中文需要）
          preserve_interword_spaces: '1',            // 保留词间空格
          tessjs_create_hocr: '0',                  // 禁用HOCR输出（加速）
          tessjs_create_tsv: '0',                   // 禁用TSV输出（加速）
          tessjs_create_box: '0',                   // 禁用BOX输出（加速）
          tessjs_create_unlv: '0',                  // 禁用UNLV输出（加速）
          tessjs_create_osd: '0',                   // 禁用OSD输出（加速）
        })
        
        ocrWorkerRef.current = worker
        setOcrReady(true)
        console.log('[悬浮窗] ✅ OCR引擎初始化成功（优化模式）!')
      } catch (error) {
        console.error('[悬浮窗] OCR引擎初始化失败:', error)
        try {
          const worker = await createWorker('chi_sim', 1, {
            logger: (m) => {
              if (m.status === 'initializing language' || m.status === 'initialized api') {
                console.log('[悬浮窗-OCR]', m.status)
              }
            },
          })
          // 使用优化配置
          await worker.setParameters({
            tessedit_pageseg_mode: PSM.SINGLE_BLOCK,
            preserve_interword_spaces: '1',
            tessjs_create_hocr: '0',
            tessjs_create_tsv: '0',
            tessjs_create_box: '0',
            tessjs_create_unlv: '0',
            tessjs_create_osd: '0',
          })
          ocrWorkerRef.current = worker
          setOcrReady(true)
          console.log('[悬浮窗] ✅ OCR引擎使用默认配置初始化成功!')
        } catch (err) {
          console.error('[悬浮窗] OCR引擎完全失败:', err)
        }
      }
    }

    initOCR()

    return () => {
      if (ocrWorkerRef.current) {
        ocrWorkerRef.current.terminate()
        ocrWorkerRef.current = null
      }
    }
  }, [ocrEngine])

  // 初始化 AudioContext（在用户交互时调用）
  const initAudioContext = useCallback(() => {
    if (!audioContextInitialized.current) {
      try {
        if (audioContextRef.current) {
          audioContextRef.current.close()
        }
        const ctx = new AudioContext()
        audioContextRef.current = ctx
        audioContextInitialized.current = true
        console.log('[悬浮窗-音频] AudioContext 已激活，状态:', ctx.state)
        
        // 如果是 suspended 状态，尝试恢复
        if (ctx.state === 'suspended') {
          ctx.resume().then(() => {
            console.log('[悬浮窗-音频] AudioContext 已恢复')
          })
        }
      } catch (error) {
        console.error('[悬浮窗-音频] AudioContext 初始化失败:', error)
      }
    }
  }, [])

  // 播放默认警报音（嘟嘟嘟）
  const playDefaultAlertSound = useCallback(async () => {
    console.log('[悬浮窗-警报] ========== 播放默认警报音 ==========')
    
    // 确保 AudioContext 已初始化
    if (!audioContextRef.current || audioContextRef.current.state === 'closed') {
      console.log('[悬浮窗-警报] AudioContext 未初始化，正在初始化...')
      initAudioContext()
    }
    
    // 如果还是没有 AudioContext，直接返回
    if (!audioContextRef.current) {
      console.error('[悬浮窗-警报] ❌ AudioContext 初始化失败，无法播放音频')
      alert('⚠️ 音频系统初始化失败，请重新启动监控！')
      return
    }
    
    const audioContext = audioContextRef.current
    
    // 如果是 suspended 状态，先恢复它
    if (audioContext.state === 'suspended') {
      console.log('[悬浮窗-警报] ⏸️ AudioContext 是 suspended 状态，正在恢复...')
      try {
        await audioContext.resume()
        console.log('[悬浮窗-警报] ✅ AudioContext 已恢复，当前状态:', audioContext.state)
      } catch (error) {
        console.error('[悬浮窗-警报] ❌ AudioContext 恢复失败:', error)
        alert('⚠️ 音频系统恢复失败，请重新启动监控！')
        return
      }
    }
    
    console.log('[悬浮窗-警报] ▶️ AudioContext 当前状态:', audioContext.state)
    
    if (audioContext.state !== 'running') {
      console.error('[悬浮窗-警报] ❌ AudioContext 状态不是 running，无法播放')
      alert('⚠️ 音频系统状态异常，请重新启动监控！')
      return
    }
    
    currentAlertActive.current = true
    
    const playOnce = () => {
      return new Promise<void>(resolve => {
        const oscillator = audioContext.createOscillator()
        const gainNode = audioContext.createGain()
        
        oscillator.connect(gainNode)
        gainNode.connect(audioContext.destination)
        
        oscillator.frequency.value = 800
        oscillator.type = 'sine'
        
        gainNode.gain.setValueAtTime(alertVolume / 100, audioContext.currentTime)
        gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3)
        
        oscillator.start(audioContext.currentTime)
        oscillator.stop(audioContext.currentTime + 0.3)
        
        oscillator.onended = () => resolve()
      })
    }

    // 连续播放多次
    (async () => {
      for (let i = 0; i < 3; i++) {
        if (!currentAlertActive.current) return
        await playOnce()
        await new Promise(resolve => setTimeout(resolve, 200))
      }

      // 如果设置了循环，继续播放
      if (alertRepeat === 0) {
        // 无限循环
        alertIntervalRef.current = setInterval(async () => {
          if (currentAlertActive.current) {
            for (let i = 0; i < 3; i++) {
              if (!currentAlertActive.current) break
              await playOnce()
              await new Promise(resolve => setTimeout(resolve, 200))
            }
          } else {
            if (alertIntervalRef.current) {
              clearInterval(alertIntervalRef.current)
              alertIntervalRef.current = null
            }
          }
        }, 2000)
      } else if (alertRepeat > 1) {
        // 有限次循环
        const remainingCount = alertRepeat - 1
        let count = 0
        alertIntervalRef.current = setInterval(async () => {
          if (count < remainingCount && currentAlertActive.current) {
            for (let i = 0; i < 3; i++) {
              if (!currentAlertActive.current) break
              await playOnce()
              await new Promise(resolve => setTimeout(resolve, 200))
            }
            count++
          } else {
            if (alertIntervalRef.current) {
              clearInterval(alertIntervalRef.current)
              alertIntervalRef.current = null
            }
            console.log('[悬浮窗-警报] 默认警报音循环播放完成')
          }
        }, 2000)
      } else {
        console.log('[悬浮窗-警报] 默认警报音只播放1次')
      }
    })()
  }, [alertVolume, alertRepeat, initAudioContext])

  // 播放警报音（自定义音频或默认音）
  const playAlertSound = useCallback(async () => {
    console.log('[悬浮窗-警报] ========== 开始播放警报音 ==========')
    console.log('[悬浮窗-警报] 配置信息:', {
      audioFilePath: audioFilePath || '未设置',
      alertVolume,
      alertRepeat: alertRepeat === 0 ? '无限循环' : alertRepeat + '次',
      hasIpcRenderer: !!window.ipcRenderer
    })
    
    // 先停止所有之前的音频
    if (alertIntervalRef.current) {
      clearInterval(alertIntervalRef.current)
      alertIntervalRef.current = null
    }
    
    // ⚠️ 不要关闭 audioContextRef，让默认音可以继续使用
    // 只停止自定义音频播放
    if (window.ipcRenderer) {
      try {
        window.ipcRenderer.send('tts:stop-audio')
      } catch (error) {
        console.error('[悬浮窗-警报] 停止自定义音频失败:', error)
      }
    }
    
    // 标记警报为激活状态
    currentAlertActive.current = true
    
    // 如果选择了音频文件，播放该音频文件
    if (audioFilePath && audioFilePath.trim() && window.ipcRenderer) {
      console.log('[悬浮窗-警报] ✅ 使用自定义音频文件:', audioFilePath)
      console.log('[悬浮窗-警报] 🔊 开始播放自定义音频...')
      
      // 定义播放函数（返回 Promise）
      const playCustomAudio = async (): Promise<boolean> => {
        if (!currentAlertActive.current) return false
        
        try {
          console.log('[悬浮窗-警报] 开始播放音频...')
          const result = await window.ipcRenderer.invoke('liveWakeup:playAudioFile', {
            filePath: audioFilePath,
            volume: alertVolume
          })
          
          if (!result.success) {
            console.error('[悬浮窗-警报] 音频文件播放失败:', result.error)
            return false
          }
          
          console.log('[悬浮窗-警报] 音频播放完成')
          return true
        } catch (error) {
          console.error('[悬浮窗-警报] 播放音频文件异常:', error)
          return false
        }
      }
      
      // 定义循环播放函数
      const playLoop = async () => {
        let playCount = 0
        const totalCount = alertRepeat
        
        console.log('[悬浮窗-警报] 循环设置: alertRepeat =', totalCount)
        
        if (totalCount === 0) {
          // 无限循环
          console.log('[悬浮窗-警报] 开始无限循环播放')
          while (currentAlertActive.current) {
            playCount++
            console.log(`[悬浮窗-警报] 播放第 ${playCount} 次自定义音频`)
            const success = await playCustomAudio()
            if (!success) {
              console.error('[悬浮窗-警报] ❌ 自定义音频播放失败，回退到默认警报音')
              // 重新初始化 AudioContext 并播放默认音
              initAudioContext()
              setTimeout(() => playDefaultAlertSound(), 100)
              return
            }
            console.log(`[悬浮窗-警报] 第 ${playCount} 次播放完成`)
            // 等待 500ms 再播放下一次，避免音频冲突
            if (currentAlertActive.current) {
              await new Promise(resolve => setTimeout(resolve, 500))
            }
          }
          console.log('[悬浮窗-警报] 无限循环结束（用户手动停止）')
        } else if (totalCount > 0) {
          // 有限次循环
          console.log(`[悬浮窗-警报] 开始有限循环播放 ${totalCount} 次`)
          while (playCount < totalCount && currentAlertActive.current) {
            playCount++
            console.log(`[悬浮窗-警报] 播放第 ${playCount}/${totalCount} 次自定义音频`)
            const success = await playCustomAudio()
            if (!success) {
              console.error('[悬浮窗-警报] ❌ 自定义音频播放失败，回退到默认警报音')
              // 重新初始化 AudioContext 并播放默认音
              initAudioContext()
              setTimeout(() => playDefaultAlertSound(), 100)
              return
            }
            console.log(`[悬浮窗-警报] 第 ${playCount}/${totalCount} 次播放完成`)
            // 等待 500ms 再播放下一次，避免音频冲突（但最后一次不需要等待）
            if (playCount < totalCount && currentAlertActive.current) {
              await new Promise(resolve => setTimeout(resolve, 500))
            }
          }
          console.log(`[悬浮窗-警报] 循环播放完成，总共播放了 ${playCount} 次`)
        }
      }
      
      // 开始循环播放
      playLoop()
    } else {
      // 没有选择音频文件，播放默认的"嘟嘟嘟"警报音
      console.log('[悬浮窗-警报] ✅ 使用默认警报音（嘟嘟嘟）')
      playDefaultAlertSound()
    }
  }, [audioFilePath, alertVolume, alertRepeat, playDefaultAlertSound, initAudioContext])

  // 执行 OCR 识别（仅OCR模式）
  const performOCRRecognition = useCallback(async (data: {
    screenshot: string
    keywords: string[]
    saveScreenshot: boolean
  }) => {
    if (!ocrWorkerRef.current) {
      console.error('[悬浮窗-OCR模式] Worker 未初始化')
      return
    }

    try {
      console.log('[悬浮窗-OCR模式] 开始文字识别...')
      const { data: { text } } = await ocrWorkerRef.current.recognize(data.screenshot)
      
      // 识别完成后，立即检查监控是否已停止
      if (!isMonitoringRef.current) {
        console.log('[悬浮窗-OCR模式] ❌ 识别完成但监控已停止，不触发警报')
        return
      }
      
      // 打印完整的识别内容
      console.log('[悬浮窗-OCR模式] ========== 识别内容开始 ==========')
      console.log(text)
      console.log('[悬浮窗-OCR模式] ========== 识别内容结束 ==========')
      
      const normalizedText = text.toLowerCase().replace(/\s/g, '')
      
      console.log('[悬浮窗-OCR模式] 规范化后的文本片段:', normalizedText.substring(0, 100))
      console.log('[悬浮窗-OCR模式] 文本总长度:', text.length, '字符')

      // 检查关键词
      for (const keyword of data.keywords) {
        const normalizedKeyword = keyword.toLowerCase().replace(/\s/g, '')
        if (normalizedText.includes(normalizedKeyword)) {
          console.log('[悬浮窗-OCR模式] 🚨 检测到关键词:', keyword)
          
          // 再次检查监控状态（双重保险）
          if (!isMonitoringRef.current) {
            console.log('[悬浮窗-OCR模式] ❌ 准备触发警报时发现监控已停止，取消警报')
            return
          }
          
          // 触发警报
          setLastKeyword(keyword)
          setAlertActive(true)
          
          // 🔴 立即停止监控，避免重复触发
          console.log('[悬浮窗-监控] 检测到关键词，自动停止监控')
          isMonitoringRef.current = false
          setIsMonitoring(false)
          
          // 调用主进程停止监控
          if (window.ipcRenderer) {
            try {
              await window.ipcRenderer.invoke('liveWakeup:stop')
            } catch (error) {
              console.error('[悬浮窗-监控] 停止监控失败:', error)
            }
          }
          
          // 根据叫醒模式选择不同的提醒方式
          console.log('[悬浮窗-叫醒] 检查叫醒模式配置:', {
            wakeupMode,
            hasPhoneNumber: !!phoneNumber.trim(),
            aliCloudInitialized,
            hasIpcRenderer: !!window.ipcRenderer
          })
          
          if (wakeupMode === 'phone' && phoneNumber.trim() && aliCloudInitialized && window.ipcRenderer) {
            // 电话叫醒模式
            console.log('[悬浮窗-叫醒] ✅ 使用电话叫醒模式，电话:', phoneNumber)
            try {
              const result = await window.ipcRenderer.invoke('liveWakeup:sendWakeupCall' as any, {
                phoneNumber: phoneNumber.trim(),
                message: `检测到关键词"${keyword}"，请立即查看直播状态！`
              }) as VoiceCallResult
              
              if (result.success) {
                console.log(`[悬浮窗-叫醒] ✅ 电话叫醒成功，通话ID: ${result.callId}`)
              } else {
                console.error(`[悬浮窗-叫醒] ❌ 电话叫醒失败: ${result.error}，回退到音频模式`)
                // 电话叫醒失败时，回退到音频警报
                playAlertSound()
              }
            } catch (error) {
              console.error('[悬浮窗-叫醒] ❌ 电话叫醒异常:', error, '，回退到音频模式')
              // 异常时回退到音频警报
              playAlertSound()
            }
          } else {
            // 音频叫醒模式或电话模式配置不完整时
            console.log('[悬浮窗-叫醒] ✅ 使用音频叫醒模式')
            playAlertSound()
          }
          
          break
        }
      }
    } catch (error) {
      console.error('[悬浮窗-OCR模式] 识别失败:', error)
    }
  }, [playAlertSound, wakeupMode, phoneNumber, aliCloudInitialized])

  // 监听来自主进程的 OCR 请求（仅 Tesseract 引擎使用）
  useEffect(() => {
    if (!window.ipcRenderer) {
      console.error('[悬浮窗-OCR模式] ❌ ipcRenderer 不可用')
      return
    }

    const unsubscribe = window.ipcRenderer.on(
      'liveWakeup:performOCR',
      (data: { screenshot: string; keywords: string[]; saveScreenshot: boolean }) => {
        if (!isMonitoringRef.current) {
          console.log('[悬浮窗-OCR模式] ❌ 忽略请求 - 监控已停止')
          return
        }
        
        // 如果使用 Umi-OCR，主进程会处理 OCR，不会发送到这里
        if (ocrEngine === 'umi-ocr') {
          console.log('[悬浮窗-OCR模式] 使用 Umi-OCR，主进程已处理识别')
          return
        }
        
        if (!ocrReady) {
          console.log('[悬浮窗-OCR模式] ⏳ 忽略请求 - OCR未就绪')
          return
        }
        
        console.log('[悬浮窗-OCR模式] ✅ 接收到 Tesseract OCR 请求，开始处理...')
        performOCRRecognition(data)
      }
    )

    return () => {
      unsubscribe()
    }
  }, [ocrReady, performOCRRecognition, ocrEngine])

  // 停止音频播放（通用函数）
  const stopAudioPlayback = useCallback(() => {
    console.log('[悬浮窗-音频] 停止音频播放')
    
    // 停止当前激活的警报
    currentAlertActive.current = false
    
    // 清除定时器
    if (alertIntervalRef.current) {
      clearInterval(alertIntervalRef.current)
      alertIntervalRef.current = null
    }
    
    // 停止自定义音频文件播放（HTML Audio）
    if (customAudioRef.current) {
      customAudioRef.current.pause()
      customAudioRef.current.src = ''
      customAudioRef.current = null
    }
    
    // 停止自定义音频文件播放（通过主进程）
    try {
      if (window.ipcRenderer) {
        window.ipcRenderer.send('tts:stop-audio')
      }
    } catch (error) {
      console.error('[悬浮窗-音频] 发送停止音频请求失败:', error)
    }
    
    // 停止 AudioContext（默认警报音）
    if (audioContextRef.current) {
      try {
        audioContextRef.current.close()
        audioContextRef.current = null
      } catch (error) {
        console.error('[悬浮窗-音频] 关闭 AudioContext 失败:', error)
      }
    }
  }, [])

  // 停止警报
  const stopAlert = useCallback(() => {
    console.log('[悬浮窗-警报] 停止警报')
    
    // 更新状态
    setAlertActive(false)
    
    // 调用通用停止函数
    stopAudioPlayback()
  }, [stopAudioPlayback])

  // 监听监控停止事件
  useEffect(() => {
    if (!window.ipcRenderer) {
      console.error('[悬浮窗] ❌ ipcRenderer 不可用')
      return
    }

    const unsubscribe = window.ipcRenderer.on('liveWakeup:stoppedEvent', () => {
      console.log('[悬浮窗] 📩 收到主进程停止事件')
      isMonitoringRef.current = false
      setIsMonitoring(false)
      // 不自动停止警报，让用户手动点击"停止警报"按钮
      // stopAlert()
    })

    return () => {
      unsubscribe()
    }
  }, [stopAlert])

  // 监听警报触发事件（用于 Umi-OCR 引擎或图像匹配模式）
  useEffect(() => {
    if (!window.ipcRenderer) {
      console.error('[悬浮窗] ❌ ipcRenderer 不可用')
      return
    }

    const unsubscribe = window.ipcRenderer.on('liveWakeup:alertTriggered', (data: { 
      keyword: string
      screenshot?: string
      timestamp: number
      phoneCallSent?: boolean
    }) => {
      console.log('[悬浮窗] 📩 收到警报触发事件，关键词:', data.keyword)
      
      // 设置警报状态
      setLastKeyword(data.keyword)
      setAlertActive(true)
      
      // 停止监控
      isMonitoringRef.current = false
      setIsMonitoring(false)
      
      // 如果主进程已发送电话叫醒，不需要播放音频
      if (data.phoneCallSent) {
        console.log('[悬浮窗] 主进程已发送电话叫醒，不播放音频')
        return
      }
      
      // 播放警报音
      playAlertSound()
    })

    return () => {
      unsubscribe()
    }
  }, [playAlertSound])

  // 测试截图
  const handleTestScreenshot = async () => {
    if (!window.ipcRenderer) {
      alert('IPC 通信不可用，无法进行截图测试')
      return
    }

    setIsTestingScreenshot(true)
    try {
      console.log('[悬浮窗-测试截图] 开始截图测试...', captureRegion ? '使用选择区域' : '全屏截图')
      // 传递当前选择的区域（如果有的话）
      const result = await window.ipcRenderer.invoke('liveWakeup:capturePreview' as any, captureRegion)
      if (result.success && result.screenshot) {
        setTestScreenshot(result.screenshot)
        setShowScreenshotPreview(true)
        console.log('[悬浮窗-测试截图] 截图成功', captureRegion ? `区域: ${captureRegion.width}×${captureRegion.height}` : '全屏')
      } else {
        alert(`截图失败: ${result.error || '未知错误'}`)
      }
    } catch (error) {
      console.error('[悬浮窗-测试截图] 截图失败:', error)
      alert('截图失败，请重试')
    } finally {
      setIsTestingScreenshot(false)
    }
  }

  // 开始选择区域 - 使用屏幕区域选择器
  const handleStartSelectRegion = async () => {
    if (!window.ipcRenderer) {
      alert('IPC 通信不可用，无法进行区域选择')
      return
    }

    try {
      console.log('[悬浮窗-区域选择] 开始屏幕区域选择...')
      setIsSelectingRegion(true)
      
      const result = await window.ipcRenderer.invoke('liveWakeup:selectScreenRegion') as {
        success: boolean
        region?: { x: number; y: number; width: number; height: number } | null
        error?: string
      }
      
      if (result && result.success && result.region) {
        console.log('[悬浮窗-区域选择] 选择成功:', result.region)
        setCaptureRegion(result.region)
      } else if (result && result.region === null) {
        console.log('[悬浮窗-区域选择] 用户取消选择')
      } else {
        alert(`区域选择失败: ${result?.error || '未知错误'}`)
      }
    } catch (error) {
      console.error('[悬浮窗-区域选择] 区域选择失败:', error)
      alert('区域选择失败，请重试')
    } finally {
      setIsSelectingRegion(false)
    }
  }


  // 清除选择的区域
  const handleClearRegion = () => {
    setCaptureRegion(null)
    console.log('[悬浮窗-区域选择] 已清除选择区域')
  }

  // 打开放大预览
  const handleOpenEnlargedPreview = () => {
    setImageScale(1)
    setImagePosition({ x: 0, y: 0 })
    setShowEnlargedPreview(true)
    setShowScreenshotPreview(false)
  }

  // 关闭放大预览
  const handleCloseEnlargedPreview = () => {
    setShowEnlargedPreview(false)
    setShowScreenshotPreview(true)
  }

  // 缩放控制
  const handleZoomIn = () => {
    setImageScale(prev => Math.min(prev + 0.25, 3))
  }

  const handleZoomOut = () => {
    setImageScale(prev => Math.max(prev - 0.25, 0.1))
  }

  const handleResetZoom = () => {
    setImageScale(1)
    setImagePosition({ x: 0, y: 0 })
  }

  // 图片拖拽处理
  const handleImageMouseDown = (e: React.MouseEvent) => {
    if (imageScale > 1) {
      setIsImageDragging(true)
      setLastMousePos({ x: e.clientX, y: e.clientY })
    }
  }

  const handleImageMouseMove = (e: React.MouseEvent) => {
    if (isImageDragging && imageScale > 1) {
      const deltaX = e.clientX - lastMousePos.x
      const deltaY = e.clientY - lastMousePos.y
      
      setImagePosition(prev => ({
        x: prev.x + deltaX,
        y: prev.y + deltaY
      }))
      
      setLastMousePos({ x: e.clientX, y: e.clientY })
    }
  }

  const handleImageMouseUp = () => {
    setIsImageDragging(false)
  }

  // 滚轮缩放处理
  const handleWheel = useCallback((e: WheelEvent) => {
    if (showEnlargedPreview) {
      e.preventDefault()
      const delta = e.deltaY > 0 ? -0.1 : 0.1
      setImageScale(prev => Math.max(0.1, Math.min(3, prev + delta)))
    }
  }, [showEnlargedPreview])

  // 键盘快捷键处理
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (showEnlargedPreview) {
        switch (e.key) {
          case 'Escape':
            handleCloseEnlargedPreview()
            break
          case '=':
          case '+':
            handleZoomIn()
            break
          case '-':
            handleZoomOut()
            break
          case '0':
            handleResetZoom()
            break
        }
      }
    }

    window.addEventListener('keydown', handleKeyDown)
    window.addEventListener('wheel', handleWheel, { passive: false })
    
    return () => {
      window.removeEventListener('keydown', handleKeyDown)
      window.removeEventListener('wheel', handleWheel)
    }
  }, [showEnlargedPreview, handleWheel])

  // 启动监控 - 必须先选择监控区域
  const handleStart = async () => {
    if (!window.ipcRenderer) {
      alert('IPC 通信不可用，请重启应用')
      return
    }

    // 检查是否已选择监控区域
    if (!captureRegion) {
      alert('请先选择监控区域！')
      return
    }

    // 读取保存的配置
    const savedKeywords = localStorage.getItem('liveWakeup:keywords')
    const savedInterval = localStorage.getItem('liveWakeup:checkInterval')
    
    const keywords = savedKeywords ? JSON.parse(savedKeywords) : ['人脸识别', '身份验证', '安全验证']
    
    // 验证OCR
    if (keywords.length === 0) {
      alert('请在主窗口中至少添加一个关键词')
      return
    }

    if (!ocrReady) {
      alert('OCR 引擎正在初始化中，请稍候...')
      return
    }

    // 🔴 重要：在用户点击启动时初始化 AudioContext，绕过浏览器自动播放限制
    // 但只在需要使用默认音（没有配置自定义音频文件）时才初始化
    if (!audioFilePath || !audioFilePath.trim()) {
      console.log('[悬浮窗-音频] 用户点击启动按钮，初始化 AudioContext（使用默认音）')
      initAudioContext()
    } else {
      console.log('[悬浮窗-音频] 用户点击启动按钮，使用自定义音频，不初始化 AudioContext')
    }

    try {
      const config: LiveWakeupConfig = {
        keywords,
        checkInterval: savedInterval ? parseInt(savedInterval) : 3,
        saveScreenshot: false, // 悬浮窗不保存截图
        alertVolume: alertVolume, // 使用从 localStorage 读取的音量配置
        alertRepeat: alertRepeat, // 使用从 localStorage 读取的循环次数配置
        ocrLanguage: 'chi_sim',
        captureRegion: captureRegion, // 使用当前选择的区域
        detectionMode: 'ocr', // 只使用OCR模式
        // OCR引擎配置
        ocrEngine: {
          engine: ocrEngine,
          tesseract: {
            language: 'chi_sim',
          },
          umiOcr: ocrEngine === 'umi-ocr' ? {
            apiUrl: umiOcrApiUrl,
            language: umiOcrLanguage,
            timeout: 10000,
          } : undefined,
        },
      }

      console.log(`[悬浮窗] 启动监控，检测模式: OCR，引擎: ${ocrEngine}`)
      
      const result = await window.ipcRenderer.invoke('liveWakeup:start', config)
      
      if (result.success) {
        isMonitoringRef.current = true
        setIsMonitoring(true)
        console.log(`[悬浮窗] ✅ 监控已启动 (OCR模式)`)
      } else {
        alert(`启动失败: ${result.error}`)
      }
    } catch (error) {
      console.error('[悬浮窗] 启动监控失败:', error)
      alert('启动失败，请检查配置')
    }
  }

  // 停止监控
  const handleStop = async () => {
    if (!window.ipcRenderer) {
      console.error('[悬浮窗] ❌ ipcRenderer 不可用')
      return
    }

    try {
      console.log('[悬浮窗] 🛑 用户点击停止监控')
      isMonitoringRef.current = false
      setIsMonitoring(false)
      
      await window.ipcRenderer.invoke('liveWakeup:stop')
      
      // 不自动停止警报，让用户手动点击"停止警报"按钮
      // stopAlert()
      
      console.log('[悬浮窗] ✅ 监控已停止')
    } catch (error) {
      console.error('[悬浮窗] 停止监控失败:', error)
    }
  }

  // 关闭悬浮窗
  const handleClose = async () => {
    try {
      // 如果正在监控，先停止
      if (isMonitoring && window.ipcRenderer) {
        await handleStop()
      }
      
      // 如果有警报在播放，停止警报（因为关闭窗口后用户无法手动停止）
      if (alertActive) {
        stopAlert()
      }
      
      // 尝试通过 IPC 关闭
      if (window.ipcRenderer) {
        await window.ipcRenderer.invoke('liveWakeup:closeFloatingWindow' as any)
      } else {
        // 如果 IPC 不可用，尝试使用 window.close()
        console.warn('[悬浮窗] IPC 不可用，尝试使用 window.close()')
        window.close()
      }
    } catch (error) {
      console.error('[悬浮窗] 关闭失败:', error)
      // 最后的备用方案
      try {
        window.close()
      } catch (e) {
        console.error('[悬浮窗] window.close() 也失败:', e)
      }
    }
  }

  // 拖动窗口
  const handleWindowMouseDown = () => {
    setIsWindowDragging(true)
  }

  useEffect(() => {
    if (isWindowDragging) {
      // @ts-ignore - electron API
      window.electron?.ipcRenderer?.send('window:start-drag')
      setIsWindowDragging(false)
    }
  }, [isWindowDragging])

  // 切换简洁模式
  const toggleCompactMode = () => {
    const newMode = !compactMode
    setCompactMode(newMode)
    localStorage.setItem('liveWakeup:compactMode', newMode.toString())
  }

  return (
    <div className={`h-full text-white flex flex-col overflow-hidden ${
      compactMode 
        ? 'bg-transparent' 
        : 'bg-gradient-to-br from-slate-900 to-slate-800 rounded-lg shadow-2xl border border-slate-700'
    }`}>
      {/* 标题栏 - 可拖动 - 简洁模式下隐藏 */}
      {!compactMode && (
        <div 
          className="flex items-center justify-between px-3 py-2 bg-slate-800/50 cursor-move select-none"
          onMouseDown={handleWindowMouseDown}
          style={{ WebkitAppRegion: 'drag' } as any}
        >
          <div className="flex items-center gap-2">
            <Grip className="h-4 w-4 text-slate-400" />
            <span className="text-sm font-semibold">直播叫醒</span>
          </div>
          <div className="flex items-center gap-1">
            <button
              onClick={toggleCompactMode}
              className="hover:bg-slate-700 p-1 rounded transition-colors"
              style={{ WebkitAppRegion: 'no-drag' } as any}
              title="简洁模式"
            >
              <Minimize2 className="h-3 w-3" />
            </button>
            <button
              onClick={handleClose}
              className="hover:bg-red-500/20 p-1 rounded transition-colors"
              style={{ WebkitAppRegion: 'no-drag' } as any}
            >
              <X className="h-4 w-4" />
            </button>
          </div>
        </div>
      )}

      {/* 主内容区 */}
      <div className={`flex-1 flex flex-col ${compactMode ? 'p-0' : 'p-3 space-y-3'}`}>
        {compactMode ? (
          /* 简洁模式 - 只显示核心内容 */
          <div className="relative h-full flex items-center justify-center bg-black/80">
            {/* 悬浮控制按钮组 - 右上角 */}
            <div className="absolute top-2 right-2 flex flex-col gap-1 z-10">
              <button
                onClick={toggleCompactMode}
                className="bg-black/60 hover:bg-black/80 p-1.5 rounded transition-colors backdrop-blur-sm"
                title="完整模式"
              >
                <Maximize2 className="h-3 w-3 text-white" />
              </button>
              <button
                onClick={isMonitoring ? handleStop : handleStart}
                className={`p-1.5 rounded transition-colors backdrop-blur-sm ${
                  isMonitoring 
                    ? 'bg-red-500/80 hover:bg-red-600/80' 
                    : 'bg-green-500/80 hover:bg-green-600/80'
                }`}
                disabled={!isMonitoring && (!ocrReady || !captureRegion)}
                title={isMonitoring ? '停止监控' : '启动监控'}
              >
                {isMonitoring ? <Pause className="h-3 w-3" /> : <Play className="h-3 w-3" />}
              </button>
              {alertActive && (
                <button
                  onClick={stopAlert}
                  className="bg-red-600/80 hover:bg-red-700/80 p-1.5 rounded transition-colors backdrop-blur-sm animate-pulse"
                  title="停止警报"
                >
                  <Volume2 className="h-3 w-3" />
                </button>
              )}
            </div>

            {/* 状态显示 - 左上角 */}
            <div className="absolute top-2 left-2 z-10">
              <div className="bg-black/60 backdrop-blur-sm rounded px-2 py-1">
                <div className="flex items-center gap-1.5">
                  <div className={`h-1.5 w-1.5 rounded-full ${isMonitoring ? 'bg-green-500 animate-pulse' : 'bg-gray-500'}`} />
                  <div className="flex flex-col">
                    <span className="text-xs text-white">
                      {isMonitoring ? '监控中' : '已停止'}
                    </span>
                    {isMonitoring ? (
                      <span className="text-[10px] text-yellow-300 font-mono">
                        {countdown}秒后检测
                      </span>
                    ) : (
                      <span className="text-[10px] text-slate-300">
                        {checkInterval}秒/次
                      </span>
                    )}
                  </div>
                </div>
              </div>
            </div>

            {/* 警报提示 - 居中 */}
            {alertActive && (
              <div className="absolute inset-0 flex items-center justify-center bg-red-500/20 animate-pulse z-5">
                <div className="bg-red-600/90 backdrop-blur-sm px-4 py-2 rounded-lg">
                  <div className="flex items-center gap-2">
                    <AlertCircle className="h-5 w-5 text-white" />
                    <div>
                      <p className="text-sm font-bold text-white">检测到关键词</p>
                      <p className="text-xs text-white/90">{lastKeyword}</p>
                    </div>
                  </div>
                </div>
              </div>
            )}

            {/* 主显示区域 - 截图预览或提示 */}
            {testScreenshot ? (
              <img 
                src={testScreenshot} 
                alt="监控预览" 
                className="max-w-full max-h-full object-contain"
              />
            ) : (
              <div className="text-center text-white/50">
                <Camera className="h-12 w-12 mx-auto mb-2 opacity-30" />
                <p className="text-sm">直播监控悬浮窗</p>
                <p className="text-xs mt-1">
                  {captureRegion ? '✓ 区域已选择' : '⚠ 未选择区域'}
                </p>
              </div>
            )}
          </div>
        ) : (
          /* 完整模式 - 显示所有控制 */
          <>
            {/* IPC 不可用提示 */}
            {!ipcAvailable && (
              <div className="bg-red-500/20 border border-red-500 rounded-lg p-2">
                <div className="flex items-center gap-2">
                  <AlertCircle className="h-4 w-4 text-red-400" />
                  <div className="flex-1">
                    <p className="text-xs font-bold text-red-300">IPC 通信不可用</p>
                    <p className="text-[10px] text-red-400">请重启应用</p>
                  </div>
                </div>
              </div>
            )}

            {/* 警报提示 */}
            {alertActive && (
              <div className="bg-red-500/20 border border-red-500 rounded-lg p-2 animate-pulse">
                <div className="flex items-center gap-2">
                  <AlertCircle className="h-4 w-4 text-red-400" />
                  <div className="flex-1">
                    <p className="text-xs font-bold text-red-300">检测到关键词</p>
                    <p className="text-[10px] text-red-400">{lastKeyword}</p>
                  </div>
                  <Button
                    onClick={stopAlert}
                    size="sm"
                    variant="destructive"
                    className="h-6 text-xs px-2"
                  >
                    停止
                  </Button>
                </div>
              </div>
            )}

            {/* 状态显示 */}
            <div className="flex items-center justify-between gap-2">
              <div className="flex items-center gap-2">
                <div className={`h-1.5 w-1.5 rounded-full ${isMonitoring ? 'bg-green-500 animate-pulse' : 'bg-gray-500'}`} />
                <div className="flex flex-col">
                  <span className="text-xs">
                    {isMonitoring ? '监控中...' : '已停止'}
                  </span>
                  {isMonitoring ? (
                    <span className="text-[10px] text-yellow-300 font-mono">
                      倒计时: {countdown}秒
                    </span>
                  ) : (
                    <span className="text-[10px] text-slate-400">
                      检测间隔: {checkInterval}秒
                    </span>
                  )}
                </div>
              </div>
              <div className="text-[10px] text-slate-300">
                OCR: {ocrReady ? '✅' : '⏳'} | {ocrEngine === 'umi-ocr' ? 'Umi' : 'Tess'}
              </div>
            </div>

            {/* 监控区域状态 */}
            <div className="space-y-1">
              {captureRegion ? (
                <div className="p-1.5 bg-green-900/30 border border-green-500/30 rounded">
                  <div className="flex items-center gap-1 mb-0.5">
                    <div className="h-1 w-1 bg-green-500 rounded-full animate-pulse"></div>
                    <div className="text-[10px] font-medium text-green-400">区域已选择</div>
                  </div>
                  <div className="text-[10px] text-slate-300">
                    {captureRegion.width} × {captureRegion.height}
                  </div>
                </div>
              ) : (
                <div className="text-[10px] text-red-400">
                  ❌ 请先选择监控区域
                </div>
              )}
              
              {/* 区域选择和测试按钮 */}
              <div className="space-y-1">
                <div className="flex gap-1">
                  <Button
                    onClick={handleStartSelectRegion}
                    size="sm"
                    variant="outline"
                    className="flex-1 h-5 text-[10px] !text-white !border-white/50 hover:!bg-white hover:!text-black bg-transparent px-1"
                    disabled={isMonitoring || isSelectingRegion}
                  >
                    <Crop className="mr-0.5 h-2.5 w-2.5" />
                    {captureRegion ? '重选' : '选择'}
                  </Button>
                  {captureRegion && (
                    <Button
                      onClick={handleClearRegion}
                      size="sm"
                      variant="outline"
                      className="h-5 px-1.5 !text-white !border-white/50 hover:!bg-white hover:!text-black bg-transparent"
                      disabled={isMonitoring}
                    >
                      <X className="h-2.5 w-2.5" />
                    </Button>
                  )}
                </div>
                {/* 测试截图按钮 */}
                <Button
                  onClick={handleTestScreenshot}
                  size="sm"
                  variant="outline"
                  className="w-full h-5 text-[10px] !text-blue-300 !border-blue-500/50 hover:!bg-blue-500 hover:!text-white bg-transparent px-1"
                  disabled={isTestingScreenshot}
                >
                  <Camera className="mr-0.5 h-2.5 w-2.5" />
                  {isTestingScreenshot ? '截图中' : '测试截图'}
                </Button>
              </div>
            </div>

            {/* 测试音频按钮 */}
            <Button
              onClick={() => {
                if (isTestingAudio) {
                  console.log('[悬浮窗-测试] 用户点击停止播放')
                  stopAudioPlayback()
                  setIsTestingAudio(false)
                  isTestingAudioRef.current = false
                } else {
                  console.log('[悬浮窗-测试] 用户点击测试音频按钮')
                  if (!audioFilePath || !audioFilePath.trim()) {
                    console.log('[悬浮窗-测试] 使用默认音，初始化 AudioContext')
                    initAudioContext()
                  }
                  setIsTestingAudio(true)
                  isTestingAudioRef.current = true
                  playAlertSound()
                }
              }}
              size="sm"
              variant={isTestingAudio ? "destructive" : "outline"}
              className={isTestingAudio 
                ? "w-full h-6 text-[10px] px-1" 
                : "w-full h-6 text-[10px] !text-yellow-300 !border-yellow-500/50 hover:!bg-yellow-500 hover:!text-white bg-transparent px-1"
              }
            >
              <Volume2 className="mr-0.5 h-2.5 w-2.5" />
              {isTestingAudio ? '停止' : '测试音频'}
            </Button>

            {/* 控制按钮 */}
            <Button
              onClick={isMonitoring ? handleStop : handleStart}
              variant={isMonitoring ? 'destructive' : 'default'}
              className="w-full h-7 text-xs"
              disabled={!isMonitoring && (!ocrReady || !captureRegion)}
            >
              {isMonitoring ? (
                <>
                  <Pause className="mr-1 h-3 w-3" />
                  停止监控
                </>
              ) : (
                <>
                  <Play className="mr-1 h-3 w-3" />
                  启动监控
                </>
              )}
            </Button>

            <p className="text-[10px] text-slate-300 text-center">
              在主窗口配置关键词
            </p>
          </>
        )}
      </div>
      
      {/* 截图预览模态框 */}
      {showScreenshotPreview && testScreenshot && (
        <div className="absolute inset-0 bg-black/90 backdrop-blur-sm flex flex-col rounded-lg z-50">
          <div className="flex items-center justify-between p-3 border-b border-slate-600">
            <h3 className="text-sm font-semibold text-white">截图预览</h3>
            <div className="flex items-center gap-2">
              <button
                onClick={handleOpenEnlargedPreview}
                className="text-slate-400 hover:text-white transition-colors p-1 rounded hover:bg-slate-700"
                title="放大查看"
              >
                <ZoomIn className="h-4 w-4" />
              </button>
              <button
                onClick={() => setShowScreenshotPreview(false)}
                className="text-slate-400 hover:text-white transition-colors"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
          </div>
          <div className="flex-1 p-3 overflow-auto">
            <img 
              src={testScreenshot} 
              alt="截图预览" 
              className="w-full h-auto rounded border border-slate-600 shadow-lg cursor-pointer"
              onClick={handleOpenEnlargedPreview}
            />
          </div>
          <div className="p-3 border-t border-slate-600">
            <div className="text-xs text-slate-300 mb-2">
              {captureRegion ? (
                <>
                  💡 这是选择区域 ({captureRegion.width}×{captureRegion.height}) 的截图，监控时会检测此区域内容
                </>
              ) : (
                <>
                  💡 这是当前屏幕的截图，监控时会检测此类内容
                </>
              )}
            </div>
            <div className="flex gap-2">
              <Button
                onClick={handleOpenEnlargedPreview}
                size="sm"
                className="flex-1 bg-transparent border border-white/50 text-white hover:bg-white hover:text-black hover:border-white"
              >
                <ZoomIn className="mr-2 h-3 w-3" />
                放大查看
              </Button>
              <Button
                onClick={() => setShowScreenshotPreview(false)}
                size="sm"
                className="flex-1"
              >
                关闭预览
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* 放大预览模态框 */}
      {showEnlargedPreview && testScreenshot && (
        <div className="fixed inset-0 bg-black/95 backdrop-blur-sm flex flex-col z-[60]">
          {/* 工具栏 */}
          <div className="flex items-center justify-between p-4 border-b border-slate-600 bg-black/50">
            <div className="flex items-center gap-4">
              <h3 className="text-sm font-semibold text-white">放大预览</h3>
              <div className="text-xs text-slate-300">
                缩放: {Math.round(imageScale * 100)}%
              </div>
            </div>
            <div className="flex items-center gap-2">
              {/* 缩放控制 */}
              <button
                onClick={handleZoomOut}
                className="text-slate-400 hover:text-white transition-colors p-2 rounded hover:bg-slate-700"
                title="缩小"
              >
                <ZoomOut className="h-4 w-4" />
              </button>
              <button
                onClick={handleResetZoom}
                className="text-slate-400 hover:text-white transition-colors p-2 rounded hover:bg-slate-700"
                title="重置"
              >
                <RotateCcw className="h-4 w-4" />
              </button>
              <button
                onClick={handleZoomIn}
                className="text-slate-400 hover:text-white transition-colors p-2 rounded hover:bg-slate-700"
                title="放大"
              >
                <ZoomIn className="h-4 w-4" />
              </button>
              <div className="w-px h-6 bg-slate-600 mx-2" />
              <button
                onClick={handleCloseEnlargedPreview}
                className="text-slate-400 hover:text-white transition-colors p-2 rounded hover:bg-slate-700"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
          </div>

          {/* 图片显示区域 */}
          <div 
            className="flex-1 overflow-hidden relative cursor-grab active:cursor-grabbing"
            onMouseDown={handleImageMouseDown}
            onMouseMove={handleImageMouseMove}
            onMouseUp={handleImageMouseUp}
            onMouseLeave={handleImageMouseUp}
          >
            <div className="absolute inset-0 flex items-center justify-center">
              <img
                src={testScreenshot}
                alt="放大预览"
                className="max-w-none select-none"
                style={{
                  transform: `scale(${imageScale}) translate(${imagePosition.x}px, ${imagePosition.y}px)`,
                  transition: isImageDragging ? 'none' : 'transform 0.1s ease-out',
                }}
                draggable={false}
              />
            </div>
          </div>

          {/* 底部信息 */}
          <div className="p-4 border-t border-slate-600 bg-black/50">
            <div className="flex items-center justify-between text-xs">
              <div className="text-slate-300">
                {captureRegion ? (
                  <>选择区域 ({captureRegion.width}×{captureRegion.height}) 的截图</>
                ) : (
                  <>全屏截图</>
                )}
              </div>
              <div className="text-slate-400">
                💡 滚轮缩放 | 拖拽移动 | +/- 缩放 | 0 重置 | ESC 关闭
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

